from crewai import Agent, Crew, Process, Task
from tools.database_tool import DatabaseTool
from tools.inventory_tool import InventoryTool
from tools.payment_tool import PaymentTool
from tools.custom_tool import CustomTool
from tools.logger_tool import LoggerTool
import time

class SmartSupermarketCrew:
	"""智能超市管理系统"""
	
	def __init__(self, llm):
		self.llm = llm
		self.database_tool = DatabaseTool()
		self.inventory_tool = InventoryTool()
		self.payment_tool = PaymentTool()
		self.custom_tool = CustomTool()
		self.logger = LoggerTool()

	def create_agents(self):
		"""创建所有需要的agents"""
		self.logger.log_workflow("开始创建智能超市Agent团队", "创建", "系统")
		
		# 创建主控agent
		supervisor = Agent(
			role='超市总管理员',
			goal='理解用户需求并协调其他专家完成任务',
			backstory="""你是超市的总管理员，负责理解客户需求并决定如何处理。
			你需要判断是否需要调用其他专家，并协调他们的工作。
			对于简单的问候和查询，你可以直接回复。
			对于专业的问题，你要委派给相应的专家处理。""",
			verbose=True,
			allow_delegation=True,
			llm=self.llm,
			tools=[self.custom_tool.tool]
		)
		self.logger.log_agent_action("超市总管理员", "创建完成", {"角色": "超市总管理员", "目标": "理解用户需求并协调其他专家完成任务"})

		# 创建推荐专家agent
		recommendation_expert = Agent(
			role='商品推荐专家',
			goal='为客户提供个性化的商品推荐',
			backstory="""你是商品推荐专家，熟悉所有商品特性。
			你能根据客户需求推荐最合适的商品。""",
			verbose=True,
			llm=self.llm,
			tools=[self.database_tool.tool]
		)
		self.logger.log_agent_action("商品推荐专家", "创建完成", {"角色": "商品推荐专家", "目标": "为客户提供个性化的商品推荐"})

		# 创建库存管理agent
		inventory_manager = Agent(
			role='库存管理员',
			goal='管理商品库存，确保库存准确性',
			backstory="""你是库存管理专家，负责处理所有库存相关查询和更新。
			你能够准确回答库存情况并处理库存更新。""",
			verbose=True,
			llm=self.llm,
			tools=[self.inventory_tool.tool]
		)
		self.logger.log_agent_action("库存管理员", "创建完成", {"角色": "库存管理员", "目标": "管理商品库存，确保库存准确性"})

		# 创建支付处理agent
		payment_processor = Agent(
			role='收银员',
			goal='处理客户支付事务',
			backstory="""你是专业收银员，熟悉各种支付方式和优惠政策。
			你能够准确处理支付流程和优惠应用。""",
			verbose=True,
			llm=self.llm,
			tools=[self.payment_tool.tool]
		)
		self.logger.log_agent_action("收银员", "创建完成", {"角色": "收银员", "目标": "处理客户支付事务"})
		
		self.logger.log_workflow("Agent团队创建完成", "完成", "系统")
		return [supervisor, recommendation_expert, inventory_manager, payment_processor]

	def create_task(self, user_input: str):
		"""创建任务"""
		self.logger.log_workflow("开始创建任务")
		self.logger.log_user_interaction(user_input)
		
		agents = self.create_agents()
		supervisor = agents[0]  # 主控agent

		# 创建主任务
		task = Task(
			description=f"""
			处理用户请求: '{user_input}'
			
			作为超市总管理员，你需要：
			1. 理解用户的需求
			2. 对于简单的问候和查询，直接回复
			3. 对于专业问题，决定需要哪个专家来处理：
			   - 商品推荐专家：处理商品推荐相关问题
			   - 库存管理员：处理库存查询和更新
			   - 收银员：处理支付和订单
			4. 如果需要专家协助，说明原因并委派任务
			5. 确保得到完整的答复后再回复用户
			
			注意：
			- 推荐相关问题委派给商品推荐专家
			- 库存相关问题委派给库存管理员
			- 支付相关问题委派给收银员
			""",
			agent=supervisor,
			expected_output="完整的问题处理结果",
			context=[
				{
					"role": "user",
					"content": user_input
				},
				{
					"role": "system",
					"content": "你是超市总管理员，需要理解用户需求并决定如何处理。"
				}
			]
		)
		
		self.logger.log_workflow(f"任务创建完成: 处理用户请求 '{user_input}'", "完成", "超市总管理员")
		return task

	def process_request(self, user_input: str):
		"""处理用户请求"""
		self.logger.log_workflow("开始处理用户请求", "开始", "超市总管理员")
		self.logger.log_user_interaction(user_input)
		
		# 创建agents
		agents = self.create_agents()
		supervisor = agents[0]  # 主控agent
		recommendation_expert = agents[1]  # 推荐专家
		inventory_manager = agents[2]  # 库存管理员
		payment_processor = agents[3]  # 收银员
		
		# 记录主管思考过程
		self.logger.log_agent_thinking("超市总管理员", "分析用户需求，判断需要调用的专家...")
		self.logger.log_agent_action("超市总管理员", "开始分析", {"输入": user_input, "行为": "分析用户意图", "目标": "确定处理策略"})
		
		# 创建crew
		crew = Crew(
			agents=agents,
			tasks=[self.create_task(user_input)],
			manager_llm=self.llm,
			process=Process.hierarchical,
			verbose=True
		)
		
		self.logger.log_workflow("Crew创建完成，开始执行任务", "初始化", "超市总管理员")
		self.logger.log_agent_action("超市总管理员", "任务分配", {"任务类型": "用户请求处理", "执行阶段": "初始化", "状态": "准备分配任务"})

		# 执行任务前记录状态
		self.logger.log_workflow("开始执行Crew任务", "执行", "超市总管理员")
		self.logger.log_agent_action("超市总管理员", "启动Crew任务流程", {"任务类型": "用户请求处理", "启动时间": "现在"})
		
		# 执行任务
		start_time = time.time()
		result = crew.kickoff(inputs={"user_input": user_input})
		execution_time = time.time() - start_time
		
		# 执行任务后记录状态
		self.logger.log_workflow(f"任务执行完成，耗时: {execution_time:.2f}秒", "完成", "超市总管理员")
		self.logger.log_agent_action("超市总管理员", "处理完成", {
			"结果状态": "成功" if result else "失败", 
			"执行状态": "完成", 
			"执行时间": f"{execution_time:.2f}秒",
			"响应类型": "最终结果"
		})
		self.logger.log_agent_thinking("超市总管理员", "任务已完成，准备返回最终结果给用户...")
		self.logger.log_system_response(result, "超市总管理员")
		
		return result
		
	# 添加一个装饰器方法，用于包装工具调用并记录日志
	def log_tool_call(self, tool_func):
		"""装饰器，用于记录工具调用"""
		def wrapper(*args, **kwargs):
			tool_name = tool_func.__name__
			self.logger.log_tool_usage(tool_name, kwargs)
			result = tool_func(*args, **kwargs)
			self.logger.log_tool_usage(f"{tool_name} (结果)", None, result)
			return result
		return wrapper